package com.gzx.risk.core.utils;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.springframework.stereotype.Component;

import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.function.Consumer;

/**
 * EasyExcel 导入导出工具类（扩展监听器支持）
 * 支持实体类解析、自定义监听器解析、Excel写入等功能
 */
@Component
public class EasyExcelUtil {

    // 新增：读取指定sheet的方法
    public static <T> List<T> readExcel(File file, Class<T> clazz, int sheetNo) {
        if (file == null || !file.exists()) {
            throw new IllegalArgumentException("Excel文件不存在");
        }
        return EasyExcel.read(file)
                .head(clazz)
                .sheet(sheetNo)  // 指定sheet索引
                .doReadSync();
    }

    // 原有方法保持不变...
    /**
     * 读取Excel文件并解析为实体类列表
     */
    public static <T> List<T> readExcel(File file, Class<T> clazz) {
        if (file == null || !file.exists()) {
            throw new IllegalArgumentException("Excel文件不存在");
        }
        return EasyExcel.read(file)
                .head(clazz)
                .sheet()
                .doReadSync();
    }

    /**
     * 从输入流读取Excel并解析为实体类列表
     */
    public static <T> List<T> readExcel(InputStream inputStream, Class<T> clazz) {
        if (inputStream == null) {
            throw new IllegalArgumentException("输入流不能为空");
        }
        return EasyExcel.read(inputStream)
                .head(clazz)
                .sheet()
                .doReadSync();
    }

    /**
     * 分页读取Excel（适用于大数据量）
     */
    public static <T> void readExcelByPage(File file, Class<T> clazz, Consumer<List<T>> consumer) {
        if (file == null || !file.exists()) {
            throw new IllegalArgumentException("Excel文件不存在");
        }
        EasyExcel.read(file)
                .head(clazz)
                .sheet()
                .registerReadListener(new PageReadListener<>(consumer))
                .doRead();
    }

    /**
     * 将实体类列表写入Excel文件
     */
    public static <T> void writeExcel(File file, List<T> data, Class<T> clazz) {
        if (file == null) {
            throw new IllegalArgumentException("目标文件不能为空");
        }
        File parentFile = file.getParentFile();
        if (parentFile != null && !parentFile.exists()) {
            parentFile.mkdirs();
        }

        HorizontalCellStyleStrategy styleStrategy = getDefaultStyleStrategy();
        EasyExcel.write(file, clazz)
                .registerWriteHandler(styleStrategy)
                .sheet("数据列表")
                .doWrite(data);
    }

    /**
     * 将实体类列表写入输出流（Web下载场景）
     */
    public static <T> void writeExcel(OutputStream outputStream, List<T> data, Class<T> clazz) {
        if (outputStream == null) {
            throw new IllegalArgumentException("输出流不能为空");
        }
        HorizontalCellStyleStrategy styleStrategy = getDefaultStyleStrategy();
        EasyExcel.write(outputStream, clazz)
                .registerWriteHandler(styleStrategy)
                .sheet("数据列表")
                .doWrite(data);
    }

    /**
     * 获取默认的Excel样式策略
     */
    public static HorizontalCellStyleStrategy getDefaultStyleStrategy() {
        WriteCellStyle headStyle = new WriteCellStyle();
        headStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);

        WriteCellStyle contentStyle = new WriteCellStyle();
        contentStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);

        return new HorizontalCellStyleStrategy(headStyle, contentStyle);
    }


    public static <T> void exportWithoutTemplate(HttpServletResponse response,
                                                 String fileName,
                                                 List<T> data,
                                                 Class<T> clazz) throws IOException {
        // 1. 设置响应头信息
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");

        // 处理文件名中文乱码
        String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.name())
                .replaceAll("\\+", "%20");
        response.setHeader("Content-disposition",
                "attachment;filename*=utf-8''" + encodedFileName + ".xlsx");

        // 2. 直接写入数据（无需模板，根据实体类注解自动生成表头）
        try (OutputStream outputStream = response.getOutputStream()) {
            EasyExcel.write(outputStream, clazz)
                    .registerWriteHandler(getDefaultStyleStrategy())
                    .sheet()
                    .doWrite(data);
        }
    }

    /**
     * 生成Excel文件的输入流（使用EasyExcel在内存中生成）
     * @param dataList 数据列表
     * @param clazz 数据类（用于生成表头）
     * @return Excel文件输入流
     */
    public static InputStream generateExcelStream(List<?> dataList, Class<?> clazz) {
        try {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            EasyExcel.write(out, clazz).sheet("sheet").doWrite(dataList);
            return new ByteArrayInputStream(out.toByteArray());
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}